class OsnGroupUpdate {
    func fromJson(_ state:String, _ json:[String:Any], _ data:[String:Any]?) ->GroupUpdateInfo {
        let u = GroupUpdateInfo()
        guard let data = data else {return u}
        u.noticeServerTime = json["timestamp"] as? String ?? ""
        u.msgHash = json["hash"] as? String ?? ""
        u.groupID = json["from"] as? String ?? ""
        u.name = data["name"] as? String ?? ""
        u.owner = data["owner"] as? String ?? ""
        u.type = data["type"] as? Int ?? 0
        u.joinType = data["joinType"] as? String ?? ""
        u.passType = data["passType"] as? Int ?? 0
        u.mute = data["mute"] as? Int ?? 0
        u.singleMute = data["singleMute"] as? Int ?? 0
        u.memberCount = data["memberCount"] as? Int ?? 0
        u.portrait = data["portrait"] as? String ?? ""
        u.attribute = data["attribute"] as? String ?? ""
        u.billboard = data["billboard"] as? String ?? ""
        u.invitor = data["invitor"] as? String ?? ""
        u.approver = data["approver"] as? String ?? ""
        u.isMember = data["isMember"] as? String ?? ""
        u.extra = data["extra"] as? String ?? ""
        u.msg = data["msg"] as? String ?? ""
        u.muteRange = data["muteRange"] as? String ?? ""
        u.text = data["text"] as? String ?? ""
        u.state = data["state"] as? String ?? ""
        u.data = data
        u.notice = ""
        if state == "UpdateMember"{
            if let userList = data["userList"] as? [[String:Any]] {
                for user in userList {
                    u.memberInfo = gosnMember.fromJson(user, nil)
                    break
                }
            }
        }else{
            u.userList = data["userList"] as? [String] ?? []
        }
        return u
    }
    func fromUpdate(_ json:GroupUpdateInfo) ->DMCCGroup {
        let g = DMCCGroup()
        g.groupId = json.groupID
        g.name = json.name
        g.portrait = json.portrait
        g.owner = json.owner
        g.mute = json.mute
        g.type = json.type
        g.passType = json.passType
        g.joinType = OsnJoinType(rawValue: json.joinType)
        g.singleMute = json.singleMute
        g.memberCount = json.memberCount
        g.maxMemberCount = 200
        g.isMember = json.isMember
        g.billboard = json.billboard
        g.attribute = json.attribute
        g.extra = json.extra
        if(json.muteRange == "all"){
            g.muteRange = OsnMuteRange.all
        }else if(json.muteRange == "members"){
            g.muteRange = OsnMuteRange.members
        }else{
            g.muteRange = OsnMuteRange.you
        }
        return g
    }
    func groupUpdateNewlyGroup(_ info:GroupUpdateInfo) async {
        if gosnConversation.getConversationInfo(info.groupID) == nil {
            _ = gosnConversation.newConversation(OsnConversationType.Group, info.groupID)
        }
        _ = gosnNotify.createGroupNotify(info)
        var group = gosnGroup.getGroupInfo(info.groupID)
        if group == nil {
            group = fromUpdate(info)
            _ = gosnGroup.setGroupInfo(group!)
        }
        _ = await gosnMember.updateMemberZone(info.groupID, 0, info.memberCount)
        geventService.post(OsnEvent.GroupInfoUpdated, group!)
    }
    func groupUpdateInfo(_ info:GroupUpdateInfo, _ keys:[String]){
        if let group = gosnGroup.getGroupInfo(info.groupID) {
            for key in keys {
                if(key == "name"){
                    _ = gosnNotify.updateGroupNameNotify(info)
                    group.name = info.name
                }else if(key == "portrait"){
                    group.portrait = info.portrait
                }else if(key == "attribute"){
                    group.attribute = info.attribute
                }else if(key == "billboard"){
                    group.billboard = info.billboard
                }else if(key == "extra"){
                    group.extra = info.extra
                    if let json = OsnUtils.toJson(info.msg) {
                        if(json.keys.contains("joinType")){
                            let joinType = json["joinType"] as? String ?? ""
                            if(joinType == "free"){
                                group.joinType = OsnJoinType.free
                            }else if(joinType == "member"){
                                group.joinType = OsnJoinType.member
                            }else if(joinType == "admin"){
                                group.joinType = OsnJoinType.admin
                            }else if(joinType == "verify"){
                                group.joinType = OsnJoinType.verify
                            }else if(joinType == "password"){
                                group.joinType = OsnJoinType.password
                            }
                        }
                        if(json.keys.contains("joinPwd")){
                            group.joinPwd = json["joinPwd"] as? String ?? ""
                        }
                    }
                }
                _ = gosnGroup.setGroupInfo(group)
            }
            geventService.post(OsnEvent.GroupInfoUpdated, group)
        }
    }
    func groupUpdateGroupMember(_ info:GroupUpdateInfo, _ keys:[String]){
        if let mi = info.memberInfo{
            let member = gosnMember.getMemberInfoDefault(info.groupID, mi.memberId)
            member.alias = mi.alias
            _ = gosnMember.setMemberInfo(member)
        }
       
    }
    func groupUpdateDelMember(_ info:GroupUpdateInfo, _ state:String){
        var isMe = false
        for  member in info.userList {
            _ = gosnMember.delMemberInfo(info.groupID, member)
            if(member == gimService.mOsnId){
                isMe = true
            }
        }
        _ = gosnNotify.delMemberNotify(info)
        if let group = gosnGroup.getGroupInfo(info.groupID){
            if(isMe){
                group.isMember = "no"
            }
            group.memberCount = info.memberCount
            _ = gosnGroup.setGroupInfo(group)
            geventService.post(OsnEvent.GroupInfoUpdated,group)
        }
        
    }
    func groupUpdateAddMember(_ info:GroupUpdateInfo) async {
        for member in info.userList {
            var memberInfo = gosnMember.getMemberInfo(info.groupID, member)
            if memberInfo == nil {
                memberInfo = DMCCMember()
                memberInfo?.groupId = info.groupID
                memberInfo?.memberId = member
                _ = gosnMember.setMemberInfo(memberInfo!)
            }
            if gosnUser.getUserInfo(member) == nil {
                _ = await gosnUser.fetchUserInfo(member)
            }
        }
        _ = gosnNotify.addMemberNotify(info)
        if let group = gosnGroup.getGroupInfo(info.groupID) {
            group.memberCount = info.memberCount
            _ = gosnGroup.setGroupInfo(group)
            geventService.post(OsnEvent.GroupInfoUpdated,group)
        }
        
    }
    func groupUpdateQuitGroup(_ info:GroupUpdateInfo){
        if info.userList.contains(gimService.mOsnId) {
            return
        }
        for member in info.userList {
            _ = gosnMember.delMemberInfo(info.groupID, member)
        }
        _ = gosnNotify.quitGroupNotify(info)
    }
    func groupUpdateDelGroup(_ info:GroupUpdateInfo) {
        _ = gosnNotify.deleteGroupNotify(info)
        if let group = gosnGroup.getGroupInfo(info.groupID){
            group.mute = 1
            _ = gosnGroup.setGroupInfo(group)
        }
    }
    func groupUpdateMute(_ info:GroupUpdateInfo) {
        guard let group = gosnGroup.getGroupInfo(info.groupID) else {return}
        let mute = info.state == "Mute" ? 1 : 0
        if info.muteRange == "all" {
            group.mute = mute
        }else if info.muteRange == "you" {
            group.singleMute = mute
        }else if info.muteRange == "members" {
            group.muteRange = OsnMuteRange.members
            gosnMember.setMembersMute(info.groupID, info.userList, mute == 1 ? true : false)
        }
        _ = gosnGroup.setGroupInfo(group)
        _ = gosnNotify.muteMemberNotify(info)
        
        geventService.post(info.state == "Mute" ? OsnEvent.GroupMute : OsnEvent.GroupAllow, (group.muteRange, info.userList))
    }
    func groupUpdateAddAdmin(_ info:GroupUpdateInfo) {
        for member in info.userList {
            if let memberInfo = gosnMember.getMemberInfo(info.groupID, member){
                memberInfo.type = OsnMemberType.Admin
                _ = gosnMember.setMemberInfo(memberInfo)
            }
        }
        _ = gosnNotify.addAdminrNotify(info)
        geventService.post(OsnEvent.GroupAddAdmin, info.userList)
    }
    
    func groupUpdateDelAdmin(_ info:GroupUpdateInfo) {
        for member in info.userList {
            if let memberInfo = gosnMember.getMemberInfo(info.groupID, member){
                memberInfo.type = OsnMemberType.Normal
                _ = gosnMember.setMemberInfo(memberInfo)
            }
        }
        _ = gosnNotify.delAdminrNotify(info)
        geventService.post(OsnEvent.GroupDelAdmin, info.userList)
    }
}
let gosnGroupUpdate = OsnGroupUpdate()
